const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
module.exports = {
	mode: "production", // production|development
	entry: "./src/mian.js",
	output: {
		filename: "bundle.js",
		path: path.resolve(__dirname, "dist"),
		assetModuleFilename: "images/[contenthash][ext][query]", // 静态资源asset输出
		clean: true, //自动清理dist
	},
	module: {
		rules: [
			{
				//============== 资源模块 ===============
				test: /\.(png|svg|jpg|jpeg|gif)$/i,
				// resource 所有文件都将被发送到输出目录，并且其路径将被注入到 bundle 中
				// inline 所有文件都将作为 data URI(base64) 注入到 bundle 中(无输出)
				// source 所有文件将原样注入到 bundle 中(无输出) 不生成路径不适用于图片，一般用于txt
				// 通用资源类型 小于 8kb 的文件，将会视为 inline 模块类型，否则会被视为 resource 模块类型
				type: "asset",
				parser: {
					dataUrlCondition: {
						maxSize: 4 * 1024, //自定义inline阈值 4kb
					},
					// 函数返回true使用inline否则使用resource
					// dataUrlCondition: (source, { filename, module }) => {
					//   const content = source.toString();
					//   return content.includes('some marker');
					// },
				},
				// generator: { //生成器 优先级高于assetModuleFilename
				// 	filename: "images/[contenthash][ext][query]",
				// },
			},
			{
				test: /\.(woff|woff2|eot|ttf|otf)$/i,
				type: "asset/resource",
				generator: {
					//生成器 优先级高于assetModuleFilename
					filename: "fonts/[hash:10][ext][query]",
				},
			},
			//============== 样式loader =================
			{
				test: /\.css$/i,
				use: [
					MiniCssExtractPlugin.loader,
					"css-loader",
					{
						loader: "postcss-loader",
						options: {
							postcssOptions: {
								plugins: [
									[
										"postcss-preset-env",
										{
											// 其他选项
										},
									],
								],
							},
						},
					},
				], // 从后向前执行
			},
			{
				test: /\.less$/i,
				use: [
					MiniCssExtractPlugin.loader,
					//style-loaderCSS内容会被打包到JavaScript文件中。当JavaScript文件被加载并执行时，style-loader会动态创建一个<style>标签，并将CSS内容插入到页面的<head>中。这种处理方式会导致一个问题：在JavaScript文件加载并执行完毕之前，页面是没有样式的，因此用户会看到一个没有样式的页面（即“闪屏”现象）。
					//MiniCssExtractPlugin.loader(不支持hmr)将CSS文件从JavaScript文件中提取出来，并通过<link>标签独立加载。这样可以确保在页面加载时，CSS文件已经被加载并应用，从而避免闪屏现象
					"css-loader", //将css文件变成commonjs模块加载到js中，内容是样式字符串
					{
						loader: "postcss-loader",
						options: {
							postcssOptions: {
								plugins: [
									[
										"postcss-preset-env",
										{
											// 其他选项
										},
									],
								],
							},
						},
					},
					"less-loader", //创建style标签，添加js中的样式字符串，插入head头
				],
			},
			//============== 数据loader =================
			{
				test: /\.(csv|tsv)$/i,
				use: ["csv-loader"],
			},
			{
				test: /\.xml$/i,
				use: ["xml-loader"],
			},
			//============== babel loader ===============
			{
				test: /\.m?js$/,
				exclude: /(node_modules|bower_components)/,
				use: {
					loader: "babel-loader",
					options: {
						presets: ["@babel/preset-env"],
						//Babel 在每个文件都插入了辅助代码，使代码体积过大！下面的配置禁用了 Babel 自动对每个文件的 runtime 注入，而是引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引用。
						plugins: ["@babel/plugin-transform-runtime"],
					},
				},
			},
		],
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: "./index.html", //模板源
			filename: "index.html", //文件名 名称为index时，devServer默认展示html，否则展示静态资源服务器
			inject: "body", //注入js的位置 body|head
		}),
		new MiniCssExtractPlugin({
			filename: "styles/[contenthash].css",
		}), // 替代css-loader
	],
	// ============ 优化 =============
	optimization: {
		// 压缩（生产模式打包生效）
		minimizer: [new CssMinimizerPlugin()], // css压缩（生产模式下默认压缩html和js）
	},
	devServer: {
		static: "./public", // 静态资源服务器，默认public文件夹
		host: "localhost", //域名
		port: 8080, // 端口号
		open: true, //自动打开浏览器
	},
}
